## Магические методы `__len__, __abs__`

Рассмотрим, так называемые, магические методы, которые определены в каждом классе и записываются через два подчеркивания вначале и в конце имен, например, так:

`__str__, __repr__`

их еще называют

> dunder-методами (от англ. сокращения double underscope)

Каждый магический метод автоматически срабатывает в определенный момент времени, например:


Следующие два магических метода:

`__len__()` – позволяет применять функцию `len()` к экземплярам класса;

`__abs__()` - позволяет применять функцию `abs()` к экземплярам класса.

Их использование достаточно простое и очевидное. 
Давайте для примера представим, что у нас есть класс `Point`, который может хранить произвольный вектор координат точек, и определим его так:

```python
class Point:
    def __init__(self, *args):
        self.__coords = args
```
А, далее, по программе нам бы хотелось определять размерность координат с помощью функции `len()`, следующим образом:

```python
p = Point(1, 2)
print(len(p))
```
Если сейчас запустить программу, то увидим ошибку, так как функция `len` не применима к экземплярам классов по умолчанию. 

Как вы уже догадались, чтобы изменить это поведение, можно переопределить магический метод `__len__()` и в нашем случае это можно сделать так:

```python
    def __len__(self):
        return len(self.__coords)
```
Смотрите, мы здесь возвращаем размер списка `__coords` и если после этого запустить программу, то как раз это значение и будет выведено в консоль. 

То есть, магический метод `__len__` указал, что нужно возвращать, в момент применения функции `len()` к экземпляру класса. Как видите, все просто и очевидно.

Следующий магический метод `__abs__ `работает аналогичным образом, только активируется в момент вызова функции `abs` для экземпляра класса, например, так:

```python
print(abs(p))
```
Опять же, если сейчас выполнить программу, то увидим ошибку, т.к. функция `abs` не может быть напрямую применена к экземпляру. Но, если переопределить магический метод:

```python
    def __abs__(self):
        return list( map(abs, self.__coords))
```
который возвращает список из абсолютных значений координат точки, то программа отработает в штатном режиме и мы увидим ожидаемый результат.

Вот так можно использовать эти два магических метода. 
